package com.nlp.visualization.controller.jersey.controller;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.nlp.visualization.common.CONSTANTS;
import com.nlp.visualization.controller.jersey.error.ErrorCode;
import com.nlp.visualization.core.format.FormatUtils;
import com.nlp.visualization.core.seg.SegmentType;
import com.nlp.visualization.core.seg.SegmentTypeUtils;
import com.nlp.visualization.core.seg.filter.SegFilter;
import com.nlp.visualization.crawler.launcher.StartCommon;
import com.nlp.visualization.crawler.pipeline.SegmentTask;
import com.nlp.visualization.pojo.NLP.seg.ApiSegmentEntity;
import com.nlp.visualization.pojo.NLP.seg.SegmentEntity;
import com.nlp.visualization.pojo.common.AjaxReturn;
import com.nlp.visualization.pojo.crawler.PlainHtml;
import com.nlp.visualization.service.ICrawlerService;
import com.nlp.visualization.service.IDataSegmentService;
import com.nlp.visualization.service.IDataService;
import com.nlp.visualization.utils.ConvertUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;

import static com.nlp.visualization.common.CONSTANTS.ERROR_UPLOAD;

@Controller
@Path("/analysis")
public class SegmentController {

    @Autowired
    private IDataService dataService;

    @Autowired
    private IDataSegmentService dataSegmentService;

    @Autowired
    private ICrawlerService crawlerService;

    private Logger logger = LoggerFactory.getLogger(SegmentController.class);

    private Gson gson = new GsonBuilder().setPrettyPrinting().create();

    private final String CONTENXT = CONSTANTS.CONTEXT;


    @POST
    @Path("/segment")
    @Produces(MediaType.APPLICATION_JSON)
    public String normalSeg(String json) {
        boolean IsFilterP = false;
        boolean IsNoStopwords = false;
        String text;
        String type;
        SegFilter.FilterBuilder filterBuilder = new SegFilter.FilterBuilder();
        SegFilter filter;
        SegmentType segmentType;
        try {
            Map map = ConvertUtils.jsonToMap(json);
            text = (String) map.get("text");
            type = (String) map.get("type");
            segmentType = SegmentTypeUtils.getSegmentType(type);
            if (map.get("filter_sw") != null)
                IsNoStopwords = (Boolean) map.get("filter_sw");
            if (map.get("filter_p") != null)
                IsFilterP = (Boolean) map.get("filter_p");
            filter = filterBuilder.enableStopwords(IsNoStopwords).enablePunctuation(IsFilterP).build();
        } catch (Exception e) {
            logger.info("请求参数有误");
            return gson.toJson(ErrorCode.REQUEST_ARGUMENTS_ERROR);
        }

        List<String> eachSentence = dataService.splitSentences(text);
        SegmentEntity seg = dataSegmentService.seg(eachSentence, segmentType, filter);

        return gson.toJson(seg) + "";
    }


    @POST
    @Path("/segment/demo")
    @Consumes(MediaType.APPLICATION_JSON)
    public String apiSegment(String json) {
        try {
            Map map = ConvertUtils.jsonToMap(json);
            ApiSegmentEntity apiSegmentEntity = new ApiSegmentEntity();
            if (map.get("cunstom_filter") != null)
                apiSegmentEntity.setCunstom_filter((String) map.get("cunstom_filter"));
            else
                apiSegmentEntity.setCunstom_filter("");
            if (map.get("seg_type") != null)
                apiSegmentEntity.setSeg_type((String) map.get("seg_type"));
            else
                apiSegmentEntity.setSeg_type("HANLP_NLP");
            if (map.get("stopwords_filter") != null)
                apiSegmentEntity.setStopwords_filter((Boolean) map.get("stopwords_filter"));
            else
                apiSegmentEntity.setStopwords_filter(false);
            if (map.get("punctuation_filter") != null)
                apiSegmentEntity.setPunctuation_filter((Boolean) map.get("punctuation_filter"));
            else
                apiSegmentEntity.setPunctuation_filter(false);
            if (map.get("format") != null)
                apiSegmentEntity.setFormat((String) map.get("format"));
            else
                apiSegmentEntity.setFormat("JSON");
            if (map.get("text") != null) {

                List<ApiSegmentEntity.TextBean> textBeans = new ArrayList<>();
                JSONArray textArray = (JSONArray) map.get("text");
                Iterator iterator = textArray.iterator();
                while (iterator.hasNext()) {
                    JSONObject text = (JSONObject) iterator.next();
                    ApiSegmentEntity.TextBean textBean = new ApiSegmentEntity.TextBean();
                    textBean.setText(text.getString("text"));
                    textBeans.add(textBean);
                }
                apiSegmentEntity.setText(textBeans);
            } else {
                ApiSegmentEntity.TextBean textBean = new ApiSegmentEntity.TextBean();
                textBean.setText(" ");
                List<ApiSegmentEntity.TextBean> textBeans = new ArrayList<>();
                textBeans.add(textBean);
                apiSegmentEntity.setText(textBeans);
            }

            String result = "";
            try {
                List<SegmentEntity> resultList = new ArrayList<>();
                String[] CustomFilterWords = {""};
                SegFilter.FilterBuilder filterBuilder = new SegFilter.FilterBuilder();
                boolean IsFilterP = apiSegmentEntity.isPunctuation_filter();
                boolean IsNoStopwords = apiSegmentEntity.isStopwords_filter();
                String format = apiSegmentEntity.getFormat();
                if (apiSegmentEntity.getCunstom_filter() != null)
                    CustomFilterWords = apiSegmentEntity.getCunstom_filter().split(",");
                Set<String> customFilterSet = new HashSet();
                for (String str : CustomFilterWords) {
                    customFilterSet.add(str);
                }
                SegmentType segmentType = SegmentTypeUtils.getSegmentType(apiSegmentEntity.getSeg_type());
                SegFilter filter = filterBuilder.enablePunctuation(IsFilterP).enableStopwords(IsNoStopwords).enableCostume(customFilterSet).build();
                List<ApiSegmentEntity.TextBean> textBeans = apiSegmentEntity.getText();
                String textResult = "";
                for (ApiSegmentEntity.TextBean text : textBeans) {
                    if (format.equals("TXT")) {
                        textResult += dataSegmentService.segText(text.getText(), segmentType, filter) + "\n";
                    } else {
                        List<String> eachSentence = dataService.splitSentences(text.getText());
                        resultList.add(dataSegmentService.seg(eachSentence, segmentType, filter));
                    }
                }
                AjaxReturn ajaxReturn;
                if (format.equals("TXT"))
                    return textResult;
                ajaxReturn = new AjaxReturn(CONSTANTS.ERROR_SUCCESS, "请求成功", resultList);
                result = FormatUtils.formatObj(format, ajaxReturn);
            } catch (Exception e) {
                logger.error("传入参数异常");
                e.printStackTrace();
            }
            return result;
        } catch (Exception e) {
            AjaxReturn ajaxReturn = new AjaxReturn(CONSTANTS.ERROR_UNKNOWN, "未知错误", null);
            return gson.toJson(ajaxReturn);
        }


    }


    @POST
    @Path("/segment/url")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public String urlSegment(String json) {
        //返回的结果
        Map<String, Object> result = new HashMap<>();
        //存储链接的集合
        List<String> urls = new ArrayList<>();
        //结果中的数据
        List<Map<String, Object>> resultSrc = new ArrayList<>();
        try {
            Map map = ConvertUtils.jsonToMap(json);
            if (map.get("urls") != null) {
                JSONArray textArray = (JSONArray) map.get("urls");
                Iterator iterator = textArray.iterator();
                while (iterator.hasNext()) {
                    JSONObject text = (JSONObject) iterator.next();
                    urls.add(text.getString("url").trim());
                }
            } else if (map.get("url") != null) {
                urls.add(map.get("url").toString());
            } else {
                throw new ParseException("参数不正确", 0);
            }
        } catch (ParseException e) {
            logger.error("传入的参数不正确");
            e.printStackTrace();
            return new Gson().toJson(new AjaxReturn(CONSTANTS.ERROR_PARAM_ERROR, "参数异常"));
        } catch (Exception e) {
            return new Gson().toJson(new AjaxReturn(CONSTANTS.ERROR_UNKNOWN, "未知异常"));
        }

        //开始爬虫并处理分词部分
        try {
            String[] links = new String[urls.size()];
            for (int i = 0; i < urls.size(); i++) {
                links[i] = urls.get(i);
            }
            //将爬取下来的网站存储在list中
            List<File> fileList = crawlerService.crawlAsFiles(links);
            //将文本进行分词
            Iterator<File> iterator = fileList.iterator();
            while (iterator.hasNext()) {
                File tmpFile = iterator.next();
                try {
                    //新建结果Map
                    Map<String, Object> dataMap = new HashedMap();
                    //读文件
                    String fileSttring = FileUtils.readFileToString(tmpFile);
                    //提取content部分
                    PlainHtml html = gson.fromJson(fileSttring, PlainHtml.class);
                    fileSttring = html.getContent().trim();
                    //按句子切分
                    List<String> eachLine = dataService.splitSentences(fileSttring);
                    //分词
                    SegmentEntity segmentEntity = dataSegmentService.seg(eachLine, CONSTANTS.SEGMENT_TYPE, CONSTANTS.FILTER_NO);
                    //整个文件分词后，保存到指定路径
                    File afterSegFile = dataSegmentService.segFile(tmpFile, CONTENXT, CONSTANTS.SEGMENT_TYPE, CONSTANTS.FILTER_NO);
                    //添加进结果
                    dataMap.put("fileName", tmpFile.getName());
                    dataMap.put("segResult", segmentEntity);
                    dataMap.put("txt", fileSttring);
                    dataMap.put("download", afterSegFile.getPath().split(CONTENXT + "/")[1]);
                    resultSrc.add(dataMap);
                    logger.info("成功解析URL的文件：" + tmpFile.getName());
                } catch (IOException e) {
                    return IOExcepction(e, result);
                }

            }
            result.put("status", 0);
            result.put("msg", "上传成功");
            result.put("data", resultSrc);

            return gson.toJson(result);

        } catch (Exception e) {
            return new Gson().toJson(new AjaxReturn(CONSTANTS.ERROR_UNKNOWN, "未知异常"));
        }

    }

    private String IOExcepction(IOException e, Map<String, Object> result) {
        result.put("status", ERROR_UPLOAD);
        result.put("msg", "上传异常");
        logger.error("上传异常");
        e.printStackTrace();
        return gson.toJson(result);
    }
}
